from django.db import models
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator, MaxValueValidator
from django.core.exceptions import ValidationError
from django.utils import timezone
from builtins import dict
User = get_user_model()

class Category(models.Model):
    """
    商品分类模型（达梦优化版）
    """
    ROOT_CATEGORIES = [
        ('electronics', '数码电子'),    # 电子设备整机
        ('accessories', '数码配件'),    # 外设周边产品
        ('academicBooks', '教材教辅'), # 教育考试类书籍
        ('generalBooks', '大众书籍'),  # 非教材类书籍
        ('clothing', '服饰穿搭'),       # 成衣穿戴品类
        ('shoesBags', '鞋靴箱包'),     # 足部用品与包具
        ('furniture', '家具家居'),      # 大型生活设施
        ('appliances', '家用电器'),     # 功率型电器
        ('sportsEquip', '运动装备'),   # 专项运动器材
        ('fitnessGear', '健身器材'),   # 健身专用设备
        ('beautyCare', '美妆个护'),    # 个人护理品
        ('photography', '摄影器材'),    # 影像创作设备
        ('musicInstruments', '乐器'),  # 音乐演奏设备
        ('officeEquip', '办公设备'),   # 办公硬件设施
        ('stationery', '文具耗材'),     # 学习消耗品
        ('toysGames', '潮玩模型'),     # 娱乐收藏品
        ('petSupplies', '宠物用品'),   # 动物养护商品
        ('travelGear', '出行装备'),    # 户外活动用品
        ('cooking', '厨房用具'),        # 烹饪相关器具
        ('jewelry', '饰品配件'),        # 个人装饰物品
        ('artCrafts', '艺术创作'),     # 创意手工材料
        ('babyCare', '母婴用品'),      # 育儿相关产品
        ('ticketsVouchers', '票务卡券'),   # 凭证类资源
        ('virtualAssets', '虚拟资产'), # 数字权益类
        ('repairServices', '维修服务'),# 售后服务类
        ('knowledgeServices', '知识服务'), # 智力支持
        ('dailyNecessities','日用百货'), # 生活消耗品
        ('collectibles', '收藏品类'),   # 收藏型物品
        ('campusServices', '校园服务'), # 校园特色服务
        ('others','其他闲置'),
    ]
    name = models.CharField(
        max_length=50,
        verbose_name='分类名称',
    )
    parent = models.ForeignKey(
       'self',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        db_column='parent_id',
        verbose_name='父分类',
    )
    is_root = models.BooleanField(
        default=False,
        verbose_name='是否为一级分类', 
    )
    sort_order=models.PositiveIntegerField(default=0, verbose_name="排序权重")
    def clean(self):
        """验证分类层级"""
        if self.is_root and self.parent:
            raise ValidationError("一级分类不能有父分类")
        if not self.is_root and not self.parent:
            raise ValidationError("二级分类必须指定父分类")
        if self.is_root and self.name not in dict(self.ROOT_CATEGORIES).keys():
            raise ValidationError("一级分类必须是预设分类")
    class Meta:
        db_table = 'CATEGORY'
        verbose_name = '商品分类'
        verbose_name_plural = verbose_name

        # 达梦建议：显式禁用自动权限和索引
        default_permissions = ()
        managed = True

    @property
    def display_name(self):
        """获取分类的中文显示名称"""
        if self.is_root:
            return dict(self.ROOT_CATEGORIES).get(self.name, self.name)
        return self.name
    
    def __str__(self):
        return self.display_name  # 修改这里，返回中文名


class Product(models.Model):
    """
    商品状态优化方案：
    - 草稿(0): 仅保存未发布
    - 已上架(1): 可被购买
    - 交易中(2): 已下单但未完成(锁定状态)
    - 已完成(3): 交易成功(可评价)
    - 已下架(4): 手动下架
    - 已关闭(5): 交易关闭(超时/退款)
    """
    STATUS_CHOICES = (
        (0, '草稿'),
        (1, '已上架'),
        (2, '交易中'), 
        (3, '已完成'),
        (4, '已下架'),
        (5, '已关闭')
    )

    DELIVERY_CHOICES = (
        (0, '包邮'),
        (1, '按距离计费'),
        (2, '一口价'),
        (3, '无需邮寄'),
    )

    product_code = models.CharField(
        max_length=30,
        unique=True,
        verbose_name='商品编码',
    )
    name = models.CharField(
        max_length=100,
        verbose_name='商品名称',
    )
    description = models.TextField(
        verbose_name='商品描述',
        null=True,
        blank=True,
    )
    price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        validators=[MinValueValidator(0.01)],
        verbose_name='商品价格',
    )
    seller = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        db_column='seller_id',
        db_index=False,  # 禁用自动索引
        verbose_name='卖家',
    )
    category = models.ForeignKey(
        Category,
        on_delete=models.CASCADE,
        db_column='category_id',
        verbose_name='商品分类',
        db_index=False,  # 禁用自动索引
    )
    status = models.SmallIntegerField(
        choices=STATUS_CHOICES,
        default=0,
        verbose_name='商品状态'
    )
    delivery_method = models.SmallIntegerField(
        choices=DELIVERY_CHOICES,
        default=0,
        verbose_name='发货方式',
    )
    delivery_location = models.CharField(
        max_length=100,
        verbose_name='发货地',
        help_text='如：北京市海淀区',
        null=True,
        blank=True,
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='发布时间',
    )
    def clean(self):
        if self.pk and self.images.count() > 9:
            raise ValidationError('每个商品最多上传9张图片')

    def save(self, *args, **kwargs):
        """保存时自动生成商品编码（格式：CATEGORY_日期_随机码）"""
        if not self.product_code:
            import random
            import string
            
            # 获取分类前缀
            category = self.category
            if not category.is_root:
                category = category.parent  # 获取父级(一级)分类
            category_name = category.name  # 直接使用分类的name字段
            
            date_str = timezone.now().strftime("%Y%m%d")
            
            # 生成4位随机字母数字组合（排除易混淆字符）
            chars = string.ascii_uppercase + string.digits
            chars = chars.translate(str.maketrans('', '', 'IO01'))  # 排除易混淆字符
            
            max_attempts = 10
            for _ in range(max_attempts):
                random_part = ''.join(random.choices(chars, k=4))
                new_code = f"{category_name}_{date_str}_{random_part}"
                
                # 检查是否已存在
                if not Product.objects.filter(product_code=new_code).exists():
                    self.product_code = new_code
                    break
            else:
                # 如果随机尝试失败，回退到原有序号方案
                today_start = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
                today_end = today_start + timezone.timedelta(days=1)
                last_id = Product.objects.filter(
                    category=self.category,
                    created_at__gte=today_start,
                    created_at__lt=today_end
                ).count()
                self.product_code = f"{category_name}_{date_str}_{last_id + 1:04d}"
        
        super().save(*args, **kwargs)

    class Meta:
        db_table = 'PRODUCTS'
        verbose_name = '商品'
        verbose_name_plural = verbose_name
        ordering = ['-created_at']

        # 显式定义所有索引（避免自动创建）
        indexes = [
            models.Index(
                fields=['seller'],
                name='IDX_PROD_SELLER',
                db_tablespace='SECONDTRADE'
            ),
            models.Index(
                fields=['category'],
                name='IDX_PROD_CATEGORY',
                db_tablespace='SECONDTRADE'
            ),
        ]
        # 达梦建议配置
        default_permissions = ()
        managed = True

    def __str__(self):
        return self.name

class ProductImage(models.Model):
    """
    商品图片模型（达梦优化版）
    显式定义所有索引，避免达梦默认索引导致的删表问题
    """
    product = models.ForeignKey(
        'Product',
        on_delete=models.CASCADE,
        db_column='product_id',
        related_name='images',
        verbose_name='所属商品',
        db_index=False  # 禁用自动索引，改为显式定义
    )

    image_url = models.CharField(  # 改为CharField而不是URLField
        max_length=255,
        verbose_name='图片路径',
        help_text='七牛云存储的相对路径'
    )
    display_order = models.PositiveSmallIntegerField(
        default=0,
        verbose_name='展示顺序',
        validators=[MaxValueValidator(8)],
        help_text='数值越小排序越前（0-8）'
    )
    size = models.PositiveIntegerField(
        verbose_name='文件大小（字节）',
        null=True,
        blank=True
    )
    @property
    def entire_image_url(self):
        from utils.qiniu_tools import ImageHandler
        return ImageHandler().get_public_url(self.image_url)
    
    @property
    def thumbnail_url(self):
        """获取缩略图URL"""
        from utils.qiniu_tools import ImageHandler
        return f"{ImageHandler().get_public_url(self.image_url)}?imageView2/2/w/220"

    @property
    def large_url(self):
        """获取大图URL"""
        from utils.qiniu_tools import ImageHandler
        handler = ImageHandler()
        return f"{handler.get_public_url(self.image_key)}{settings.IMAGE_STYLE['large']}"
    
    class Meta:
        db_table = 'PRODUCT_IMAGE'  # 达梦要求表名大写
        verbose_name = '商品图片'
        verbose_name_plural = verbose_name
        ordering = ['display_order']
        default_permissions = ()
        # 显式定义所有索引
        indexes = [
            models.Index(
                fields=['product'],
                name='IDX_PROD_IMG_PRODUCT',
            ),
            models.Index(
                fields=['display_order'],
                name='IDX_PROD_IMG_ORDER'
            )
        ]
        
    def __str__(self):
        return f"{self.product.name}-图片{self.id}"

class Favorite(models.Model):
    """
    收藏模型（达梦优化版）
    """
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        db_column='user_id',
        related_name='favorites',
        verbose_name='收藏者',
        db_index=False,  # 禁用自动索引

    )
    product = models.ForeignKey(
        Product,
        on_delete=models.CASCADE,
        db_column='product_id',
        related_name='favorited_by',
        verbose_name='商品',
        db_index=False,  # 禁用自动索引

    )
    favorited_time = models.DateTimeField(
        auto_now_add=True,
        verbose_name='收藏时间',

    )

    class Meta:
        db_table = 'FAVORITE'
        verbose_name = '收藏'
        verbose_name_plural = verbose_name

        # 复合唯一约束
        unique_together = ('user', 'product')
        # 显式定义所有索引
        indexes = [
            models.Index(
                fields=['user'],
                name='IDX_FAVORITE_USER',
                db_tablespace='SECONDTRADE'
            ),
            models.Index(
                fields=['product'],
                name='IDX_FAVORITE_PROD',
                db_tablespace='SECONDTRADE'
            ),
        ]
        # 达梦建议配置
        default_permissions = ()
        managed = True

    def __str__(self):
        return f"{self.user_id}收藏{self.product_id}"